//===============金逸晨2.42  4PIN IIC OLED==================
#include "stm32f0xx.h"
#include "Public.h"

#include "OLED.h"
#include "OLEDfont.h" 
//#include "sys_delay.h"
//

#define OLED_COLUMN_NUMBER 128
#define OLED_LINE_NUMBER 64
#define OLED_PAGE_NUMBER (OLED_LINE_NUMBER/8)
#define OLED_COLUMN_OFFSET 0
#define OLED_LINE_OFFSET 0
#define OLED_CMD_NUMBER 25

const unsigned char  OLED_init_cmd[OLED_CMD_NUMBER]=
{
  
      0xAE,//关闭显示
	
       0xD5,//设置时钟分频因子,震荡频率
       0x80,  //[3:0],分频因子;[7:4],震荡频率

       0xA8,//设置驱动路数
       0X3F,//默认(1/64)
	
       0xD3,//设置显示偏移
       0X00,//默认为0
	
       0x40,//设置显示开始行 [5:0],行数.
	
       0x8D,//电荷泵设置
       0x10,//bit2，开启/关闭
       0x20,//设置内存地址模式
       0x02,//[1:0],00，列地址模式;01，行地址模式;10,页地址模式;默认10;
       0xA1,//段重定义设置,bit0:0,0->0;1,0->127;  A1
	
       0xC8,//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 (C0 翻转显示) C8
	   
       0xDA,//设置COM硬件引脚配置
       0x12,//[5:4]配置  
	   
       0x81,//对比度设置
       0xf0,//1~255;默认0X7F (亮度设置,越大越亮)
	   
       0xD9,//设置预充电周期
       0x71,//[3:0],PHASE 1;[7:4],PHASE 2;
	   
       0xDB,//设置VCOMH 电压倍率
       0x00,//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
	   
       0xA4,//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
	   
       0xA6,//设置显示方式;bit0:1,反相显示;0,正常显示 
       
       0xAF,//开启显示   
};

const unsigned char  picture_tab[]={
//图片显示，列行式，低位在前，阴码
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01

};


void OLED_Init(void)
  {
    unsigned char i;
    for(i=0;i<24;i++)
    {
      Write_IIC_Command(OLED_init_cmd[i]);
    }
    OLED_Clear();  //先清屏后显示
    Write_IIC_Command(OLED_init_cmd[24]);//先清屏后显示
  }




void IIC_Start(void)
{
    delay_us(2);
    OLED_SCLK_Set() ;
        delay_us(2);
    OLED_SDIN_Set();
        delay_us(2);
    OLED_SDIN_Clr();
        delay_us(2);
    OLED_SCLK_Clr();
}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop(void)
{
        delay_us(2);
  OLED_SCLK_Set() ;
    // delay_us(2);
    //	OLED_SCLK_Clr();
          delay_us(2);
    OLED_SDIN_Clr();
        delay_us(2);
    OLED_SDIN_Set();
	
}

void IIC_Wait_Ack(void)
{

	//GPIOB->CRH &= 0XFFF0FFFF;	//设置PB12为上拉输入模式
	//GPIOB->CRH |= 0x00080000;
//	OLED_SDA = 1;
//	delay_us(2);
	//OLED_SCL = 1;
	//delay_us(50000);
/*	while(1)
	{
		if(!OLED_SDA)				//判断是否接收到OLED 应答信号
		{
			//GPIOB->CRH &= 0XFFF0FFFF;	//设置PB12为通用推免输出模式
			//GPIOB->CRH |= 0x00030000;
			return;
		}
	}
*/
      delay_us(2);
  OLED_SCLK_Set() ;
      delay_us(2);
  OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/

void Write_IIC_Byte(u8 IIC_Byte)
{
  u8 i;
  u8 m,da;
  da=IIC_Byte;
  OLED_SCLK_Clr();
  for(i=0;i<8;i++)		
  {
    m=da;
    //	OLED_SCLK_Clr();
    m=m&0x80;
    if(m==0x80)
    {OLED_SDIN_Set();}
    else OLED_SDIN_Clr();
    da=da<<1;
    delay_us(2);
    OLED_SCLK_Set();
    delay_us(2);    
    OLED_SCLK_Clr();
  }


}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(u8 IIC_Command)
{
    IIC_Start();
    Write_IIC_Byte(0x78);            //Slave address,SA0=0
    IIC_Wait_Ack();	
    Write_IIC_Byte(0x00);			//write command
    IIC_Wait_Ack();	
    Write_IIC_Byte(IIC_Command); 
    IIC_Wait_Ack();	
    IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(u8 IIC_Data)
{
    IIC_Start();
    Write_IIC_Byte(0x78);			//D/C#=0; R/W#=0
    IIC_Wait_Ack();	
    Write_IIC_Byte(0x40);			//write data
    IIC_Wait_Ack();	
    Write_IIC_Byte(IIC_Data);
    IIC_Wait_Ack();	
    IIC_Stop();
}
void OLED_WR_Byte(u16 dat,u16 cmd)
{
  IWDG_ReloadCounter();    /*reload*/
  
  if(cmd)
  {
    Write_IIC_Data(dat);
  }
  else 
  {
    Write_IIC_Command(dat);
  }
  


}


/********************************************
// fill_Picture
********************************************/
void fill_picture(u8 fill_Data)
{
  u8 m,n;
  for(m=0;m<8;m++)
  {
    OLED_WR_Byte(0xb0+m,0);		//page0-page1
    OLED_WR_Byte(0x02,0);		//low column start address
    OLED_WR_Byte(0x10,0);		//high column start address
    for(n=0;n<128;n++)
    {
      OLED_WR_Byte(fill_Data,1);
    }
  }
}


/***********************Delay****************************************/
void Delay_50ms(u16 Del_50ms)
{
  u16 m;
  for(;Del_50ms>0;Del_50ms--)
  for(m=6245;m>0;m--);
}

void Delay_1ms(u16 Del_1ms)
{
  u8 j;
  while(Del_1ms--)
  {	
    for(j=0;j<123;j++);
  }
}

//坐标设置

void OLED_Set_Pos(u8 x, u8 y) 
{ 	
  OLED_WR_Byte(0xb0+y,OLED_CMD);
  OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);
  OLED_WR_Byte(((x+2)&0x0f),OLED_CMD); 
}   	  
////开启OLED显示    
//void OLED_Display_On(void)
//{
//  OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
//  OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
//  OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
//}
//关闭OLED显示     
//void OLED_Display_Off(void)
//{
//  OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
//  OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
//  OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
//}		   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
  u8 i,n;		    
  for(i=0;i<8;i++)  
  {  
    OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址（0~7）
    OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址
    OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
    for(n=0;n<128;n++)
    {
      OLED_WR_Byte(0,OLED_DATA); 
    }
  } //更新显示
}

//void OLED_On(void); 
//void OLED_On(void)  
//{  
//  u8 i,n;		    
//  for(i=0;i<8;i++)  
//  {  
//    OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址（0~7）
//    OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址
//    OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
//    for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); 
//  } //更新显示
//}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{      	
  u8 c=0,i=0;	
  c=chr-' ';//得到偏移后的值	
  
  
  if(display_mod==0)
  { 
    if(x>OLED_COLUMN_NUMBER-1){x=0;y=y+2;}
    if(Char_Size ==16)
    {
      OLED_Set_Pos(x,y);	
      for(i=0;i<8;i++)
      OLED_WR_Byte(~F8X16[c*16+i],OLED_DATA);
      OLED_Set_Pos(x,y+1);
      for(i=0;i<8;i++)
      OLED_WR_Byte(~F8X16[c*16+i+8],OLED_DATA);
    }
    else 
    {	
      OLED_Set_Pos(x,y);
      for(i=0;i<6;i++)
      OLED_WR_Byte(~F6x8[c][i],OLED_DATA);
            
    }    
    
  }
  else
  {
    
    if(x>OLED_COLUMN_NUMBER-1){x=0;y=y+2;}
    if(Char_Size ==16)
    {
      OLED_Set_Pos(x,y);	
      for(i=0;i<8;i++)
      OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
      OLED_Set_Pos(x,y+1);
      for(i=0;i<8;i++)
      OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
    }
    else 
    {	
      OLED_Set_Pos(x,y);
      for(i=0;i<6;i++)
      OLED_WR_Byte(F6x8[c][i],OLED_DATA);
            
    }    
  }  


}
//m^n函数

u32 oled_pow(u8 m,u8 n);

u32 oled_pow(u8 m,u8 n)
{
  u32 result=1;	 
  while(n--)result*=m;    
  return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{         	
  u8 t,temp;
  u8 enshow=0;
  
  for(t=0;t<len;t++)
  {
    temp=(num/oled_pow(10,len-t-1))%10;
    if(enshow==0&&t<(len-1))
    {
      if(temp==0)
      {
        OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
        continue;
      }
      else 
      enshow=1; 
             
    }
    OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
  }
} 
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,char *chr,u8 Char_Size)
{
  u8 j=0;
  while (chr[j]!='\0')
  {		
    OLED_ShowChar(x,y,chr[j],Char_Size);
    x+=8;
    if(x>120)
    {
      x=0;y+=2;
    }
    j++;
  }
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{      			    
    
    if(display_mod==1)
    {
      u8 t,adder=0;
      OLED_Set_Pos(x,y);	
      for(t=0;t<16;t++)
      {

        OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
        adder+=1;
      }	
      OLED_Set_Pos(x,y+1);	
      for(t=0;t<16;t++)
      {	
        OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
        adder+=1;
      }    
    }
    else
    {
      u8 t,adder=0;
      OLED_Set_Pos(x,y);	
      for(t=0;t<16;t++)
      {

        OLED_WR_Byte(~Hzk[2*no][t],OLED_DATA);
        adder+=1;
      }	
      OLED_Set_Pos(x,y+1);	
      for(t=0;t<16;t++)
      {	
        OLED_WR_Byte(~Hzk[2*no+1][t],OLED_DATA);
        adder+=1;
      }    
    }      
  
}
/***********功能描述：显示显示BMP图片128×64起始点坐标(x,y),x的范围0～127，y为页的范围0～7*****************/
void OLED_DrawBMP(u8 x0, u8 y0,u8 x1, u8 y1,u8 BMP[])
{ 	
  u16 j=0;
  u8 x,y;

  if(y1%8==0) 
  {
    y=y1/8;
  }
  else 
  {
    y=y1/8+1;
  }
  for(y=y0;y<y1;y++)
  {
    OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
    {      
      OLED_WR_Byte(BMP[j++],OLED_DATA);	    	
    }
  }
} 